package com.venus.common.utils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DateUtil{
	
	private static final Log log = LogFactory.getLog(DateUtil.class);
	
	private static Calendar calendar = Calendar.getInstance();
	
	/**
	 * 得到当前时间的时间戳
	 * @return
	 */
	public static Timestamp getCurrentTimestamp(){
		long lTime = System.currentTimeMillis();
		Timestamp ts = new Timestamp(lTime);
		return ts;
	}
	
	/**
	 * 格式化显示字符串时间
	 * @param strDate
	 * @param strFormat
	 * @return
	 */
	public static Date parseDate(String strDate, String strFormat){
		SimpleDateFormat formatter = new SimpleDateFormat(strFormat);
		Date d = null;
		try {
			d = formatter.parse(strDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return d;
	}
	
	public static Calendar dateToCalendar(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal;
	}

	public static Date stringToUtilDate(String dateString, String strDateFormat) {
		SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
		java.util.Date date = null;
		try {
			date = sdf.parse(dateString);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
	
	public static Date stringToSqlDate(String strFormat, String strDate) {
		//SimpleDateFormat sdf = new SimpleDateFormat(strFormat);
		java.sql.Date date = null;
		try {
			date = java.sql.Date.valueOf(strDate);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		}
		return date;
	}
	
	public static String Date2String(Date date, String strDateFormat){
		SimpleDateFormat format = new SimpleDateFormat(strDateFormat);
		return format.format(date);
	}

	public static int getCurrentYear() {
		return calendar.get(Calendar.YEAR);
	}

	public static int getCurrentMonth() {
		return calendar.get(Calendar.MONTH) + 1;
	}

	public static int getCurrentDay() {
		return calendar.get(Calendar.DAY_OF_MONTH);
	}

	public static int getCurrentWeek() {
		return getWeekOfYear(Calendar.getInstance());
	}

	public static int getWeekOfYear(Calendar cal) {
		return cal.get(3);
	}

	public static int getMonthDays(String strDate, String strFormat) {
		SimpleDateFormat sdf = new SimpleDateFormat(strFormat);
		Calendar calendar = new GregorianCalendar();
		Date assignDate = null;
		try {
			assignDate = sdf.parse(strDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		calendar.setTime(assignDate);
		return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	public static String addDate(String oldDate, int num, int type) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar cd = Calendar.getInstance();
			cd.setTime(sdf.parse(oldDate));
			if (type == 1)
				cd.add(Calendar.DATE, num);
			else if (type == 2)
				cd.add(Calendar.MONTH, num);
			else if (type == 3)
				cd.add(Calendar.YEAR, num);
			return sdf.format(cd.getTime());
		} catch (Exception e) {
			return null;
		}
	}

	public static Date backwordDay(Date d, int days) {
		calendar.setTime(d);
		calendar.add(Calendar.DATE, -days);
		return calendar.getTime();
	}

	public static Date forwordDay(Date d, int days) {
		calendar.setTime(d);
		calendar.add(Calendar.DATE, days);
		return calendar.getTime();
	}

	public static Date backwordMonth(Date d, int months) {
		calendar.setTime(d);
		calendar.add(Calendar.MONTH, -months);
		return calendar.getTime();
	}

	public static Date forwordMonth(Date d, int months) {
		calendar.setTime(d);
		calendar.add(Calendar.MONTH, months);
		return calendar.getTime();
	}

	public static Date backwordYear(Date d, int years) {
		calendar.setTime(d);
		calendar.add(Calendar.YEAR, -years);
		return calendar.getTime();
	}

	public static Date forwordYear(Date d, int years) {
		calendar.setTime(d);
		calendar.add(Calendar.YEAR, years);
		return calendar.getTime();
	}

	public static int getIntervalDays(Date startday, Date endday) {
		if (startday.after(endday)) {
			Date cal = startday;
			startday = endday;
			endday = cal;
		}
		long sl = startday.getTime();
		long el = endday.getTime();
		long ei = el - sl;
		return (int) (ei / (1000 * 60 * 60 * 24));
	}

	public static int getIntervalDays(Calendar startday, Calendar endday) {
		if (startday.after(endday)) {
			Calendar cal = startday;
			startday = endday;
			endday = cal;
		}
		long sl = startday.getTimeInMillis();
		long el = endday.getTimeInMillis();
		long ei = el - sl;
		return (int) (ei / (1000 * 60 * 60 * 24));
	}
	
	public static List<String> getYearMonths(int startYear, int startMonth,
			int endYear, int endMonth) {
		List<String> lst = new ArrayList<String>();
		for (int i = startYear; i <= endYear; i++) {
			for (int j = 1; j <= 12; j++) {
				if ((i != startYear || j >= startMonth)
						&& (i != endYear || j <= endMonth)) {
					String monthStr = "";
					if (j < 10) {
						monthStr = (new StringBuilder("0")).append(j)
								.toString();
					} else {
						monthStr = Integer.toString(j);
					}
					String yearMonth = (new StringBuilder(String
							.valueOf(Integer.toString(i)))).append(monthStr)
							.toString();
					lst.add(yearMonth);
				}
			}
		}
		return lst;
	}
	
	public static Calendar getWeekStartDate(int year, int week) {
		Calendar cal = Calendar.getInstance();
		cal.set(1, year);
		cal.set(3, week);
		cal.set(7, 1);
		return cal;
	}
	
	public static Calendar getWeekEndDate(int year, int week) {
		Calendar cal = getWeekStartDate(year, week);
		cal.add(6, 6);
		return cal;
	}
	
	public static Date[] getMonthIntervalDay(String strDate, String strDateFormat){
		if(strDateFormat.equals("")){
			log.error("日期格式不能为NULL!");
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(stringToUtilDate(strDate, strDateFormat));
		int istart = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
		int iend = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		int iyear = cal.get(Calendar.YEAR);
		int imonth = cal.get(Calendar.MONTH) + 1;
		
		Date[] dates = new Date[2];
		dates[0] = stringToSqlDate(strDateFormat, iyear+"-"+imonth+"-"+istart);
		dates[1] = stringToSqlDate(strDateFormat, iyear+"-"+imonth+"-"+iend);
		
		return dates;
	}
	
	public static Date[] getMonthIntervalLastYear(String strDate, String strDateFormat){
		Date[] dates = new Date[2];
		// 当前月的前一年月份
		Calendar last = Calendar.getInstance();
		last.setTime(stringToUtilDate(strDate, strDateFormat));
		last.roll(Calendar.MONTH, -12);
		last.roll(Calendar.YEAR, -1);
		last.set(Calendar.DAY_OF_MONTH, 1);
		
		Calendar end = Calendar.getInstance();
		end.setTime(stringToUtilDate(strDate, strDateFormat));
		end.set(Calendar.DAY_OF_MONTH, end.getActualMaximum(Calendar.DAY_OF_MONTH));
		
		// 开始时间
		dates[0] = stringToSqlDate(strDateFormat, last.get(Calendar.YEAR)+"-"+(last.get(Calendar.MONTH)+1)+"-1");
		dates[1] = stringToSqlDate(strDateFormat, end.get(Calendar.YEAR)+"-"+(end.get(Calendar.MONTH)+1)+"-"+end.get(Calendar.DAY_OF_MONTH));
		
		return dates;
	}
	
	public static Date[] getCurrentYearIntervalDate(String strDate, String strDateFormat){
		Date[] dates = new Date[2];
		// 当前月的前一年月份
		Calendar begin = Calendar.getInstance();
		begin.setTime(stringToUtilDate(strDate, strDateFormat));
		begin.set(Calendar.MONTH, 0);
		begin.set(Calendar.DAY_OF_MONTH, 1);
		
		Calendar end = Calendar.getInstance();
		end.setTime(stringToUtilDate(strDate, strDateFormat));
		end.set(Calendar.MONTH, 11);
		end.set(Calendar.DAY_OF_MONTH, end.getActualMaximum(Calendar.DAY_OF_MONTH));
		// 开始时间
		dates[0] = stringToSqlDate("yyyy-MM-dd", DateUtil.Date2String(begin.getTime(), "yyyy-MM-dd"));
		dates[1] = stringToSqlDate("yyyy-MM-dd", DateUtil.Date2String(end.getTime(), "yyyy-MM-dd"));
		
		return dates;
	}
	
	/**
	 * 得到月份下所有天的日期
	 * @param strDate : 2011-11
	 * @param strDateFormat 
	 * @return
	 */
	public static Date[] getMonthDayDates(String strDate){
		// 向后退一天
		Date dateStart = backwordDay(getMonthFirstDay(strDate, "yyyy-MM"), 1);
		// 月份的天数
		int iday = getMonthDays(strDate, "yyyy-MM");
		// 月份每天的日期数组
		Date[] dates = new Date[iday];
		for(int i=0;i<iday;i++){
			dateStart = forwordDay(dateStart, 1);
			dates[i] = dateStart;
		}
		return dates;
	}
	
	/**
	 * 得到年份下所有月份的日期
	 * @param strDate
	 * @param strDateFormat
	 * @return
	 */
	public static Date[] getYearMonthDates(String strDate, String strDateFormat){
		// 向后退一月
		Date dateStart = backwordMonth(stringToUtilDate(strDate, strDateFormat), 1);
		// 一年中月份的日期数组
		Date[] dates = new Date[12];
		for(int i=0;i<12;i++){
			dateStart = forwordMonth(dateStart, 1);
			dates[i] = dateStart;
		}
		return dates;
	}
	
	/**  
	 * 得到本月的第一天  
	 * @return  
	 */  
	public static Date getMonthFirstDay(String strDate, String strDateFormat) {
	    Calendar calendar = Calendar.getInstance();
	    calendar.setTime(stringToUtilDate(strDate, strDateFormat));
	    calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
	    SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
	    String date = sdf.format(calendar.getTime());
	    return stringToUtilDate(date, strDateFormat);
	}   
	  
	/**  
	 * 得到本月的最后一天  
	 *   
	 * @return  
	 */  
	public static Date getMonthLastDay(String strDate, String strDateFormat){   
	    Calendar calendar = Calendar.getInstance();
	    calendar.setTime(stringToUtilDate(strDate, strDateFormat));
	    calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));   
	    SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
	    String date = sdf.format(calendar.getTime());
	    return stringToUtilDate(date, strDateFormat);
	}   

	public static void main(String[] args) {
		Date[] ds = DateUtil.getMonthDayDates("2011-11");
		for(Date d : ds){
			//Date dd = getMonthLastDay(DateUtil.Date2String(d, "yyyy-MM-dd"), "yyyy-MM-dd");
			System.out.println(DateUtil.Date2String(d, "yyyy-MM-dd"));
		}
		System.out.println("2011-11-11".substring(0, "2011-11-11".lastIndexOf("-")));
	}
}